;;;
;;; fuse
;;;

(define-module fuse
  (use gauche.threads)
  (export-all)
  )
(select-module fuse)

;; Loads extension
(dynamic-load "fuse")

;;
;; Put your Scheme definitions here
;;

(define (getattr path::<string> -> <sys-stat>))
(define (readlink path::<string> -> <string>))
(define (mknod path::<string> mode::<octal int> rdev::<int> -> <void>))
(define (mkdir path::<string> mode::<octal int> -> <void>))
(define (unlink path::<string> -> <void>))
(define (rmdir path::<string> -> <void>))
(define (symlink from::<string> to::<string> -> <void>))
(define (rename from::<string> to::<string> -> <void>))
(define (link from::<string> to::<string> -> <void>))
(define (chmod path::<string> mode::<octal int> -> <void>))
(define (chown path::<string> uid::<int> gid::<int> -> <void>))
(define (truncate path::<string> size::<int> -> <void>))
(define (open path::<string> file-info::<fuse-file-info> -> <void>))
(define (read path::<string> outp::<output port> size::<int> offset::<int> file-info::<fuse-file-info> -> <void>))
(define (write path::<string> inp::<input port> size::<int> offset::<int> file-info::<fuse-file-info> -> <void>))
(define (statfs path::<string> -> <sys-statvfs>))
(define (flush path::<string> file-info::<fuse-file-info> -> <void>))
(define (release path::<string> file-info::<fuse-file-info> -> <void>))
(define (fsync path::<string> datasync?::<boolean> file-info::<fuse-file-info> -> <void>))
(define (setxattr path::<string> name::<string> value::<string> size::<int> flags::<int> -> <void>))
(define (getxattr path::<string> name::<string> value::<string> size::<int> -> <string>))
(define (listxattr path::<string> list::<string> size::<int> -> <string list>))
(define (removexattr path::<string> name::<string> -> <void>))
(define (opendir path::<string> file-info::<fuse-file-info> -> <void>))
(define (readdir path::<string> file-info::<fuse-file-info> -> <string list>))
(define (releasedir path::<string> file-info::<fuse-file-info> -> <void>))
(define (fsyncdir path::<string> datasync?::<boolean> file-info::<fuse-file-info> -> <void>))
(define (init <void> -> <void>))
(define (destroy <void> -> <void>))
(define (access path::<string> mask::<int> -> <boolean>))
(define (create path::<string> mode::<octat int> file-info::<fuse-file-info> -> <void>))
(define (ftruncate path::<string> size::<int> file-info::<fuse-file-info> -> <void>))
(define (fgetattr path::<string> file-info::<fuse-file-info> -> <sys-stat>))
(define (utimens path::<string> atime::<int> mtime::<int> -> <void>))
(define (start-fuse mountpoint::<string> . operations)
  (let-keywords* operations ((args (list "" "-f" "-s" "-d" mountpoint))
			     (multithreaded #f)
			     (getattr #f)
			     (readlink #f)
			     (mknod #f)
			     (mkdir #f)
			     (unlink #f)
			     (rmdir #f)
			     (symlink #f)
			     (rename #f)
			     (link #f)
			     (chmod #f)
			     (chown #f)
			     (truncate #f)
			     (open #f)
			     (read #f)
			     (write #f)
			     (statfs #f)
			     (flush #f)
			     (release #f)
			     (fsync #f)
			     (setxattr #f)
			     (getxattr #f)
			     (listxattr #f)
			     (removexattr #f)
			     (opendir #f)
			     (readdir #f)
			     (releasedir #f)
			     (fsyncdir #f)
			     (init #f)
			     (destroy #f)
			     (access #f)
			     (create #f)
			     (ftruncate #f)
			     (fgetattr #f)
			     (utimens #f))))

(define-class <sys-stat> ()
  ())

(define (sys-stat->file-type-set! stat::<sys-stat> v::<symbol> -> <void>)
  (body <void> "
   struct stat *stat = &((ScmSysStat*)(obj))->statrec;
   if (SCM_EQ(v,SCM_INTERN(\"directory\"))) stat->st_mode |= S_IFDIR;
   if (SCM_EQ(v,SCM_INTERN(\"regular\"))) stat->st_mode |= S_IFREG;
   if (SCM_EQ(v,SCM_INTERN(\"character\"))) stat->st_mode |= S_IFCHR;
   if (SCM_EQ(v,SCM_INTERN(\"block\"))) stat->st_mode |= S_IFBLK;
   if (SCM_EQ(v,SCM_INTERN(\"fifo\"))) stat->st_mode |= S_IFIFO;
   #ifdef S_ISLNK
     if (SCM_EQ(v,SCM_INTERN(\"symlink\"))) stat->st_mode |= S_IFLNK;
   #endif
   #ifdef S_ISSOCK
     if (SCM_EQ(v,SCM_INTERN(\"socket\"))) stat->st_mode |= S_IFSOCK;
   #endif
  "))

(define (sys-stat->perm-set! stat::<sys-stat> v::<int> -> <void>)
  (body <void> "
  struct stat *stat = &((ScmSysStat*)(obj))->statrec;
  stat->st_mode = (stat->st_mode & 0xFE00) | v;
  "))

(define (sys-stat->mode-set! stat::<sys-stat> v::<int> -> <void>)
  (body <void> "
  struct stat *stat = &((ScmSysStat*)(obj))->statrec;
  stat->st_mode = v;
  "))

(define (sys-stat->ino-set! stat::<sys-stat> v::<int> -> <void>)
  (body <void> "
  struct stat *stat = &((ScmSysStat*)(obj))->statrec;
  stat->st_ino = v;
  "))

(define (sys-stat->dev-set! stat::<sys-stat> v::<int> -> <void>)
  (body <void> "
  struct stat *stat = &((ScmSysStat*)(obj))->statrec;
  stat->st_dev = v;
  "))

(define (sys-stat->rdev-set! stat::<sys-stat> v::<int> -> <void>)
  (body <void> "
  struct stat *stat = &((ScmSysStat*)(obj))->statrec;
  stat->st_rdev = v;
  "))

(define (sys-stat->nlink-set! stat::<sys-stat> v::<int> -> <void>)
  (body <void> "
  struct stat *stat = &((ScmSysStat*)(obj))->statrec;
  stat->st_nlink = v;
  "))

(define (sys-stat->size-set! stat::<sys-stat> v::<int> -> <void>)
  (body <void> "
  struct stat *stat = &((ScmSysStat*)(obj))->statrec;
  stat->st_size = Scm_IntegerToOffset(v);
  "))

(define (sys-stat->uid-set! stat::<sys-stat> v::<int> -> <void>)
  (body <void> "
  struct stat *stat = &((ScmSysStat*)(obj))->statrec;
  stat->st_uid = v;
  "))

(define (sys-stat->gid-set! stat::<sys-stat> v::<int> -> <void>)
  (body <void> "
  struct stat *stat = &((ScmSysStat*)(obj))->statrec;
  stat->st_gid = v;
  "))
(define (sys-stat->atime-set! stat::<sys-stat> v::<int> -> <void>)
  (body <void> "
  struct stat *stat = &((ScmSysStat*)(obj))->statrec;
  stat->st_atime = Scm_GetSysTime(v);
  "))

(define (sys-stat->mtime-set! stat::<sys-stat> v::<int> -> <void>)
  (body <void> "
  struct stat *stat = &((ScmSysStat*)(obj))->statrec;
  stat->st_mtime = Scm_GetSysTime(v);
  "))

(define (sys-stat->ctime-set! stat::<sys-stat> v::<int> -> <void>)
  (body <void> "
  struct stat *stat = &((ScmSysStat*)(obj))->statrec;
  stat->st_ctime = Scm_GetSysTime(v);
  "))

(define-class <sys-statvfs> ()
  ((f_bsize) (f_frsize) (f_blocks) (f_bfree) (f_bavail) (f_files) (f_ffree) (f_favail) (f_fsid) (f_flag) (f_namemax)))

(define-class <fuse-file-info> ()
  ((flags) (writepage) (direct_io) (keep_cache) (flush) (fh) (lock_owner)))

(define (fuse-file-info->flags fi::<fuse-file-info> -> <int>)
  (expr <int> "fi->flags"))
(define (fuse-file-info->flags-set! fi::<fuse-file-info> v::<int> -> <void>)
  (body <void> "fi->flags = v;"))
(define (fuse-file-info->writepage fi::<fuse-file-info> -> <int>)
  (expr <int> "fi->writepage"))
(define (fuse-file-info->writepage-set! fi::<fuse-file-info> v::<int> -> <void>)
  (body <void> "fi->writepage = v;"))
(define (fuse-file-info->direct_io fi::<fuse-file-info> -> <boolean>)
  (expr <boolean> "fi->direct_io"))
(define (fuse-file-info->direct_io-set! fi::<fuse-file-info> v::<boolean> -> <void>)
  (body <void> "fi->direct_io = (v)? 1 : 0;"))
(define (fuse-file-info->keep_cache fi::<fuse-file-info> -> <boolean>)
  (expr <boolean> "fi->keep_cache"))
(define (fuse-file-info->keep_cache-set! fi::<fuse-file-info> v::<boolean> -> <void>)
  (body <void> "fi->keep_cache = (v)? 1 : 0;"))
(define (fuse-file-info->flush fi::<fuse-file-info> -> <boolean>)
  (expr <boolean> "fi->flush"))
(define (fuse-file-info->flush-set! fi::<fuse-file-info> v::<boolean> -> <void>)
  (body <void> "fi->flush = (v)? 1 : 0;"))
(define (fuse-file-info->fh fi::<fuse-file-info> -> <int>)
  (expr <ulong> "fi->fh"))
(define (fuse-file-info->fh-set! fi::<fuse-file-info> v::<int> -> <void>)
  (body <void> "fi->fh = v;"))
(define (fuse-file-info->lock_owner fi::<fuse-file-info> -> <int>)
  (expr <ulong> "fi->lock_owner"))
(define (fuse-file-info->lock_owner-set! fi::<fuse-file-info> v::<int> -> <void>)
  (body <void> "fi->lock_owner = v;"))
;; Epilogue
(provide "fuse")


